package GUI;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.TreeMap;

import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

import msgParser.Message;
import msgParser.Parser;
import msgParser.Strings;
import msgParser.Validation;
import Core.Connection;
import Core.Rank;
import Core.SessionData;

public class SubForumMenu extends AbstractMenu
{
	private JLabel label;
	private JButton disconnectButton;
	private JLabel userMode;
	private JTextField userName;
	private JLabel userNameLabel;
	private JLabel userPassLabel;
	private JTextField userPass;
	private JButton loginButton;
	private JButton activationButton;
	private JLabel userMailLabel;
	private JTextField userMail;
	private JButton registerButton;
	private JButton refreshButton;
	private JLabel topics;
	private JList<String> topicList;
	private JScrollPane topicListScroll;
	private JButton lobbyButton;
	private JButton forumButton;
	private JButton logoutButton;
	private JLabel loginTitle;
	private JLabel adminOptions;
	private JButton createPost;
	private JButton deletePost;
	private JButton moderatorsButton;
	
	DefaultListModel<String> topicListModel = new DefaultListModel<String>();  
	
	public SubForumMenu(JFrame frame) 
	{
		super(frame);
		
		label = new JLabel(MainWindow.data.currentSubForum);
		label.setBounds(400-MainWindow.data.currentSubForum.length()*10,30,300,30);
		label.setFont(new Font(label.getFont().getName(),label.getFont().getStyle(), 30));
		
		loginTitle = new JLabel("Login / Register to selected forum:");
		loginTitle.setBounds(30,110,300,30);
		loginTitle.setFont(new Font(loginTitle.getFont().getName(),loginTitle.getFont().getStyle(), 15));

		userNameLabel = new JLabel("User name:");
		userNameLabel.setBounds(30,140,100,30);
		userNameLabel.setFont(new Font(userNameLabel.getFont().getName(),userNameLabel.getFont().getStyle(), 15));
		
		userMailLabel = new JLabel("E-Mail:");
		userMailLabel.setBounds(30,200,100,30);
		userMailLabel.setFont(new Font(userMailLabel.getFont().getName(),userMailLabel.getFont().getStyle(), 15));
		
		userMail = new JTextField();
		userMail.setBounds(95, 205, 160, 25);
		userMail.setFont(new Font(userMail.getFont().getName(),userMail.getFont().getStyle(), 12));
		userMail.setForeground(new Color(140,140,140));
		userMail.setText("For registration only");
		userMail.addFocusListener(new FocusListener() {
			public void focusLost(FocusEvent arg0) {}
			public void focusGained(FocusEvent arg0) {
				if(userMail.getText().equals("For registration only")) 
				{
					userMail.setText("");
					userMail.setForeground(new Color(0,0,0));
				}
			}
		});
		
		userPassLabel = new JLabel("Password:");
		userPassLabel.setBounds(30,170,100,30);
		userPassLabel.setFont(new Font(userPassLabel.getFont().getName(),userPassLabel.getFont().getStyle(), 15));
		
		userName = new JTextField();
		userName.setBounds(135, 145, 120, 25);
		userName.setFont(new Font(userName.getFont().getName(),userName.getFont().getStyle(), 15));
		
		userPass = new JPasswordField();
		userPass.setBounds(135, 175, 120, 25);
		userPass.setFont(new Font(userPass.getFont().getName(),userPass.getFont().getStyle(), 15));
		
		loginButton = new JButton("Log In");
		loginButton.setBounds(116, 235, 70, 20);
		loginButton.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	String forum = MainWindow.data.currentForum;
            	if(!Validation.validateString(userName.getText(), Validation.CHAR_FIRST | Validation.NO_SPACES | Validation.NO_SYMBOLS | Validation.HAS_LETTERS))
        		{
        			JOptionPane.showMessageDialog(null, "User name should start with a letter and contain no symbols or spaces.", "Invalid user name", JOptionPane.ERROR_MESSAGE);
            		return;
        		}
        		if(!Validation.validateString(userPass.getText(), Validation.NO_SPACES | Validation.HAS_LETTERS))
        		{
        			JOptionPane.showMessageDialog(null, "Password should start with a letter and contain no spaces.", "Invalid password", JOptionPane.ERROR_MESSAGE);
            		return;
        		}
        		MainWindow.data.currentSelectedForum = forum;
            	Connection.send(Message.createMessage(Strings.LOG_IN, userName.getText(), userPass.getText(), 
            						""+MainWindow.data.forums.get(forum)));
            }
		});
		
		activationButton = new JButton("Activate");
		activationButton.setBounds(190, 235, 85, 20);
		activationButton.addActionListener(new ActivationDialog());
		
		registerButton = new JButton("Register");
		registerButton.setBounds(27, 235, 85, 20);
		registerButton.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	String forum = MainWindow.data.currentForum;
            	if(!Validation.validateString(userName.getText(), Validation.CHAR_FIRST | Validation.NO_SPACES | Validation.NO_SYMBOLS | Validation.HAS_LETTERS))
        		{
        			JOptionPane.showMessageDialog(null, "User name should start with a letter and contain no symbols or spaces.", "Invalid user name", JOptionPane.ERROR_MESSAGE);
            		return;
        		}
        		if(!Validation.validateString(userPass.getText(), Validation.NO_SPACES | Validation.HAS_LETTERS))
        		{
        			JOptionPane.showMessageDialog(null, "Password should start with a letter and contain no spaces.", "Invalid password", JOptionPane.ERROR_MESSAGE);
            		return;
        		}
        		if(!Validation.validateString(userMail.getText(), Validation.NO_SPACES | Validation.HAS_LETTERS | Validation.IS_MAIL))
        		{
        			JOptionPane.showMessageDialog(null, "E-Mail address is invalid.", "Invalid Email", JOptionPane.ERROR_MESSAGE);
            		return;
        		}
            	int dialogResult = JOptionPane.showConfirmDialog (null, "Register to " + forum + "?","Confirm Registration",JOptionPane.WARNING_MESSAGE);
            	if(dialogResult == JOptionPane.YES_OPTION)
            	{
            		
            		Connection.send(Message.createMessage(Strings.REGISTER, userName.getText(), userPass.getText(), 
            						userMail.getText(), ""+MainWindow.data.forums.get(forum)));
            	}
            }
		});
		
		adminOptions = new JLabel("Moderator options:");
		adminOptions.setBounds(25,210,300,30);
		adminOptions.setFont(new Font(label.getFont().getName(),label.getFont().getStyle(), 15));
		
		userMode = new JLabel(MainWindow.data.rank.toString() + " mode");
		userMode.setBounds(10,500,200,30);
		userMode.setFont(new Font(label.getFont().getName(),label.getFont().getStyle(), 15));
		userMode.setForeground(new Color(0, 0, 255));
		
		topics = new JLabel("Available threads:");
		topics.setBounds(350,110,200,30);
		topics.setFont(new Font(label.getFont().getName(),label.getFont().getStyle(), 15));
		
		
		createPost = new JButton("Create Thread");
		createPost.setBounds(25, 180, 160, 20);
		createPost.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	MainWindow.switchMenu(new CreateTopicMenu(getFrame()));
            }
		});
		
		deletePost = new JButton("Remove Thread");
		deletePost.setBounds(25, 240, 160, 20);
		deletePost.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	if(topicList.getSelectedIndex() == -1)
            	{
            		JOptionPane.showMessageDialog(null, "Please select a thread.", "Error", JOptionPane.ERROR_MESSAGE);
            		return;
            	}
            	MainWindow.data.currentSelectedTopic = topicList.getSelectedValue();
            	int dialogResult = JOptionPane.showConfirmDialog (null, "Remove " + topicList.getSelectedValue() + "?","Confirm Removal",JOptionPane.WARNING_MESSAGE);
            	if(dialogResult == JOptionPane.YES_OPTION)
            	{
            		Connection.send(Message.createMessage(Strings.REMOVE_TOPIC, ""+MainWindow.data.topics.get(MainWindow.data.currentSelectedTopic)));
            	}
            }
		});
		
		moderatorsButton = new JButton("Moderators");
		moderatorsButton.setBounds(25, 270, 160, 20);
		moderatorsButton.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e) 
			{
				MainWindow.switchMenu(new SubForumModeratorsMenu(getFrame()));
			}
		});
		
		forumButton = new JButton("Back to Forum");
		forumButton.setBounds(660, 115, 130, 20);
		forumButton.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	MainWindow.switchMenu(new ForumMenu(getFrame()));
            }
		});
		
		lobbyButton = new JButton("Back to Lobby");
		lobbyButton.setBounds(660, 145, 130, 20);
		lobbyButton.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	MainWindow.switchMenu(new LobbyMenu(getFrame()));
            }
		});
		
		logoutButton = new JButton("Log out");
		logoutButton.setBounds(25, 140, 100, 20);
		logoutButton.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	Connection.send(Message.createMessage(Strings.LOGOUT));
            }
		});
		
		
		topicList = new JList<String>(topicListModel);
		topicList.setBorder(new EmptyBorder(4,4,4,4));
		topicList.setFixedCellHeight(30);
		topicList.setFixedCellWidth(100);
		//subForumList.setBounds(350, 140, 300, 400);
		topicList.setFont(new Font("Courier New",label.getFont().getStyle(), 18));
		topicListScroll = new JScrollPane(topicList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		topicListScroll.setPreferredSize(new Dimension(300, 100));
		topicListScroll.setBounds(350, 140, 300, 400);
		topicList.addMouseListener(new MouseAdapter() {
		    public void mouseClicked(MouseEvent evt) {
		        JList<String> list = (JList<String>)evt.getSource();
		        if(evt.getClickCount() == 1)
		        {
		        	int index = list.locationToIndex(evt.getPoint());
		        	if(index < 0) return;
		        	String name = topicListModel.get(index);
		        	MainWindow.data.currentSelectedTopic = name;
		        }
		        else if(evt.getClickCount() == 2) 
		        {         
		        	int index = list.locationToIndex(evt.getPoint());
		        	if(index < 0) return;
		        	String name = topicListModel.get(index);
		        	MainWindow.data.currentTopic = name;
		        	MainWindow.switchMenu(new TopicMenu(getFrame()));
		        } 
		        
		    }
		});
		
		disconnectButton = new JButton(new ImageIcon("disconnect.PNG"));
		disconnectButton.setBounds(10, 530, 32, 32);
		disconnectButton.setContentAreaFilled(false);
		disconnectButton.setBorder(null);
		disconnectButton.addMouseListener(new MouseAdapter() 
		{
		    public void mousePressed(MouseEvent evt) 
		    {
		    	disconnectButton.setIcon(new ImageIcon("disconnect2.PNG"));
            	disconnectButton.repaint();
		    }
		    public void mouseReleased(MouseEvent evt) 
		    {
		    	Point p = evt.getPoint();
		    	disconnectButton.setIcon(new ImageIcon("disconnect.PNG"));
            	disconnectButton.repaint();
		    	if(p.x < 0 || p.y < 0 || p.x > disconnectButton.getWidth() || p.y > disconnectButton.getHeight()) return;
            	Connection.disconnect();
            	MainWindow.data = new SessionData();
            	MainWindow.switchMenu(new ConnectMenu(getFrame()));
		    }
		});
		
		refreshButton = new JButton(new ImageIcon("refresh.PNG"));
		refreshButton.setBounds(650, 510, 30, 30);
		refreshButton.addActionListener(new ActionListener() 
		{
            public void actionPerformed(ActionEvent e)
            {
            	Connection.send(Message.createMessage(Strings.SHOW_TOPICS, ""+MainWindow.data.subForums.get(MainWindow.data.currentSubForum)));
            }
		});
	}

	public void connectionInterrupted() 
	{
		JOptionPane.showMessageDialog(null, "Connection has crashed. Please reconnect...", "Connection Error", JOptionPane.ERROR_MESSAGE);
		MainWindow.switchMenu(new ConnectMenu(getFrame()));
	}

	public void incomingMessage(String msg) 
	{
		Parser p = new Parser(msg);
		p.Parse();
		try 
		{
			if(p.testHeader(Strings.ANS_SHOW_TOPICS))
			{
				topicListModel.clear();
				topicListModel.addElement("FIX");
				topicListModel.remove(0);
				TreeMap<String, Integer> Topics = new TreeMap<String, Integer>();
				for(int i = 1; i < p.getSize(); i+=2) 
				{
					Topics.put(p.argStr(i), p.argInt(i+1));
					topicListModel.addElement(p.argStr(i));
				}
				MainWindow.data.topics = Topics;
			}
			else if(p.testHeader(Strings.ACTIVATION_NEEDED))
			{
				JOptionPane.showMessageDialog(null, "According to the forum policy, activation via E-mail is required.\nPlease click 'Activation' to activate your account.", "Activation Needed", JOptionPane.INFORMATION_MESSAGE);
				userName.setText("");
				userPass.setText("");
			}
			else if(p.testHeader(Strings.REGISTERED))
			{
				JOptionPane.showMessageDialog(null, "Registration successful. You may now login.", "Success", JOptionPane.INFORMATION_MESSAGE);
				userName.setText("");
				userPass.setText("");
			}
			else if(p.testHeader(Strings.ERROR_REGISTER))
			{
				JOptionPane.showMessageDialog(null, "Registration error: " + p.argStr(1), "Unexpected error", JOptionPane.ERROR_MESSAGE);
				userName.setText("");
				userPass.setText("");
			}
			else if(p.testHeader(Strings.LOGGED_IN))
			{
				int userId = p.argInt(1);
				MainWindow.data.myUserId = userId;
				int rank = p.argInt(2);
				MainWindow.data.loggedIn = true;
				MainWindow.data.rank = Rank.create(rank);
				JOptionPane.showMessageDialog(null, "You are now logged in as " + userName.getText() + ".", "Success", JOptionPane.INFORMATION_MESSAGE);
				MainWindow.data.currentForum = MainWindow.data.currentSelectedForum;
				MainWindow.data.currentSubForum = MainWindow.data.currentSelectedSubForum;
				MainWindow.switchMenu(new SubForumMenu(getFrame()));
			}
			else if(p.testHeader(Strings.ERROR_LOG_IN))
			{
				JOptionPane.showMessageDialog(null, "Login error: " + p.argStr(1), "Unexpected error", JOptionPane.ERROR_MESSAGE);
				userName.setText("");
				userPass.setText("");
			}
			else if(p.testHeader(Strings.LOGGED_OUT))
			{
				MainWindow.data.loggedIn = false;
				MainWindow.data.rank = Rank.GUEST;
				JOptionPane.showMessageDialog(null, "You have logged out of the system.", "Logged out", JOptionPane.INFORMATION_MESSAGE);
				MainWindow.switchMenu(new LobbyMenu(getFrame()));
			}
			else if(p.testHeader(Strings.ERROR_LOG_OUT))
			{
				JOptionPane.showMessageDialog(null, "Logout error: " + p.argStr(1), "Unexpected error", JOptionPane.ERROR_MESSAGE);
			}
			else if(p.testHeader(Strings.TOPIC_REMOVED))
			{
				JOptionPane.showMessageDialog(null, "Topic has been removed.", "Success", JOptionPane.INFORMATION_MESSAGE);
				MainWindow.switchMenu(new SubForumMenu(getFrame()));
			}
			else if(p.testHeader(Strings.ERROR_REMOVE_TOPIC))
			{
				JOptionPane.showMessageDialog(null, "Couldn't remove topic: " + p.argStr(1), "Error", JOptionPane.ERROR_MESSAGE);
			}
		} 
		catch (Exception e) {}
	}
	
	public void create() 
	{
		regItem(label);
		if(MainWindow.data.rank.getValue()==0)
		{
			regItem(userName);
			regItem(userPass);
			regItem(userNameLabel);
			regItem(userPassLabel);
			regItem(loginButton);
			regItem(registerButton);
			regItem(lobbyButton);
			regItem(loginTitle);
			regItem(activationButton);
			regItem(userMail);
			regItem(userMailLabel);
		}
		else
		{
			regItem(logoutButton);
			regItem(adminOptions);
			regItem(moderatorsButton);
			regItem(createPost);
			regItem(deletePost);
		}
		regItem(forumButton);
		regItem(topicListScroll);
		regItem(refreshButton);
		regItem(topics);
		regItem(disconnectButton);
		
		regItem(userMode);
		
		getFrame().repaint();
		Connection.send(Message.createMessage(Strings.SHOW_TOPICS, ""+MainWindow.data.subForums.get(MainWindow.data.currentSubForum)));
	}
}
